<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1" />
<title>图片动画效果</title>
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
body{background:#666;-webkit-user-select:none;-ms-user-select:none;user-select:none}
.wrap{position:fixed;top:0;right:0;bottom:0;left:0;padding:20px}
.pic{height:100%;text-align:center}
.pic_body{height:100%;display:inline-block}
.pic img{display:block;max-width:100%;max-height:100%;margin:0 auto}
.mod_loading{position:absolute;height:100%;left:0;top:0;width:100%;z-index:100;background-color:#b9ccd5;display:-webkit-box;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}
.mod_loading .content{text-align:center;-webkit-box-flex:1;flex:1;margin:0 80px}
.mod_loading .content .progress{height:13px;padding:2px;border-radius:17px;border-radius:17px;background-color:#242a39}
.mod_loading .content .progress span{display:block;height:13px;border-radius:13px;border-radius:13px;background-color:#65cfd5}
.mod_loading .content p{line-height:34px;color:#5f696a}
.menu{position:relative;position:fixed;bottom:0;left:0;font-size:.8em}
.menu select,.menu button{padding:5px}
.menu div{display:inline-block;}
.menu .item{position:relative;}
.menu .item>span{position:absolute;line-height:29px;left:.5em;}
.menu .item>select{padding-left:5em;}
.tip{position:fixed;top:0;right:0;display:block;padding:5px;font-size:.8em;background:rgba(255,255,255,.4);}
.eflist{position:fixed;width:10em;top:.5em;right:0;display:block;font-size:.8em;}
.eflist ul{padding:0;margin:0}
.eflist a,.eflist li{position:relative;color:#000;text-decoration:none;display:block;padding:.5em;text-align:center;background:rgba(255,255,255,.4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:1px;transition:height;}
.eflist a{background:rgba(255,255,255,.5);}
.eflist a:hover{background:rgba(255,255,255,.7);}
.eflist a:active{background:rgba(255,255,255,.9);}
.eflist li>i{position:absolute;left:0;top:0;bottom:0;width:0;background-color:rgba(0,0,255,.4);-webkit-transition:width .8s;transition:width .8s;}
@media screen and (max-width:500px)  {
    .wrap{padding:0;}
}
</style>
</head>

<div class="wrap">
    <div class="pic">
        <div class="pic_body"><img id="cover" /></div>
    </div>
    <div class="eflist">
        <a class="js_clear" href="jacascript:;">在图片上点击或滑动</a>
        <ul></ul>
    </div>
</div>

<div class="menu">
    <select id="js_efname"></select>
    <div id="js_opts"></div>
</div>

<div class="mod_loading">
    <div class="content">
        <div class="progress"><span style="width:0;-webkit-transition:width .5s;transition:width .5s"></span></div>
        <p>加载中...</p>
    </div>
</div>

<script src="./ct_effect.js"></script>
<!-- 玻璃破碎 -->
<script src="./ct_effect_brokenglass.js"></script>
<!-- 百叶窗 -->
<script src="./ct_effect_blinds.js"></script>
<!-- 溶解 -->
<script src="./ct_effect_dissolve.js"></script>
<!-- 平移 -->
<script src="./ct_effect_translate.js"></script>
<!-- 立方体 -->
<script src="./ct_effect_cube.js"></script>
<!-- 星星 -->
<script src="./ct_effect_star.js"></script>
<script>
var doc = document;
var $ = function(s, p){return (p && p.querySelector ? p : doc).querySelector(s)};
var $$ = function(s, p){return (p && p.querySelectorAll ? p : doc).querySelectorAll(s)};
function encodeHTML(s, br) {
    return s == null ? "" : String(s)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/ /g, "&nbsp;")
        .replace(/\'/g, "&apos;")
        .replace(/\"/g, "&quot;")
        .replace(/\r?\n/g, br != null ? br : " ");
};
function getParameter(name, href) {
    try {
        var r = new RegExp("(\\?|#|&)" + name + "=([^&#]*)(&|#|$)"),
            m = (href || location.href).match(r);
        return (!m ? "" : m[2]);
    } catch (ex) {
        console.log(ex.stack);
        return "";
    }
};
function simulateEvent(o, type) {
    var e;
    if (doc.createEvent) { // DOM Level 2 standard
        e = doc.createEvent("Events");
        e.initEvent(type, true, true);
        o.dispatchEvent(e);
    } else if (o.fireEvent) { // IE
        o.fireEvent("onclick");
    }
};
var imglist = [
    "./img/bg_1.jpg",
    "./img/bg_2.jpg",
    "./img/bg_3.jpg",
    "./img/bg_4.jpg",
    "./img/bg_5.jpg",
    "./img/bg_6.jpg",
    "./img/bg_7.jpg",
    "./img/bg_8.jpg"
];
function preloading(cb) {
    var urls = imglist, loaded = 0, pos = $(".progress>span"), timer;
    imglist = [];
    if (urls.length > 0) {
        for (var i = 0; i < urls.length; i++) {
            var img = new Image();
            img.onload = img.onerror = img.onabort = _update;
            img.src = urls[i];
        }
        timer = setTimeout(_end, 10000);
    } else {
        _end();
    }
    function _update(e) {
        if (e.type == "load") {
            imglist.push(this.src);
        }
        loaded++;
        pos.style.width = (loaded / urls.length * 100) + "%";
        if (loaded >= urls.length) {
            _end();
        }
    };
    function _end() {
        timer && clearTimeout(timer);
        $(".mod_loading").style.display = "none";
        cb && cb();
    };
};

var map_ef = {
    "fadeout": {
        params: {
            animate: "渐隐",
            target: imglist[0]
        }
    },
    "brokenglass": {
        params: {
            animate: "玻璃破碎",	// brokenglass
            target: imglist[0],
            duration: 1500,
            audio: "./audio/broken.mp3"
        },
        opts: {
            fall: {
                title: "掉落方式",
                data: {
                    "自由落体": 1,
                    "散开": 0
                }
            }
        }
    },
    "blinds": {
        params: {
            animate: "百叶窗",	// blinds
            target: imglist[0],
            audio: "./audio/effect_01.m4a",
            count: 15,
            // direct: "right",
            // origin: "edge"
        },
        opts: {
            origin: {
                title: "翻转方式",
                data: {
                    "点击处开始": "location",
                    "边缘开始": "edge"
                }
            }
        }
    },
    "dissolve": {
        params: {
            animate: "溶解",	// dissolve
            target: imglist[0],
            audio: "./audio/effect_01.m4a",
            size: 10,
            duration: 1000
        },
        opts: {
            size: {
                title: "颗粒大小",
                data: {
                    "10": "10",
                    "15": "15",
                    "20": "20",
                    "25": "25",
                    "30": "30",
                    "50": "50"
                }
            },
            direct: {
                title: "方向",
                data: {
                    "随机": "random",
                    "扩散": "point",
                    "向左": "left",
                    "向右": "right",
                    "向上": "top",
                    "向下": "bottom"
                }
            }
        }
    },
    "translate": {
        params: {
            animate: "平移",	// translate
            target: imglist[0],
            audio: "./audio/effect_01.m4a",
            "timing-function": "ease-in",
            mode: "3d",
            // direct: "left",
            duration: 1000
        },
        opts: {
            mode: {
                title: "模式",
                data: {
                    "3d": "3d",
                    "2d": "2d"
                }
            }
        }
    },
    "cube": {
        params: {
            animate: "立方体",	// cube
            target: imglist[0],
            // direct: "left",
            duration: 1000
        },
        opts: {
            direct: {
                title: "旋转方向",
                data: {
                    "自动": null,
                    "向左": "left",
                    "向右": "right",
                    "向上": "top",
                    "向下": "bottom"
                }
            }
        }
    },
    "star": {
        params: {
            animate: "星星",	// star
            target: imglist[0],
            duration: 1000
        },
        opts: {
            count: {
                title: "星星数量",
                data: {
                    "少": "4",
                    "默认": "8",
                    "多": "12"
                }
            }
        }
    }
};
function pageInit() {
    var img = $(".pic img"), cur = imglist.length * Math.random() | 0, ef;
    img.src = imglist[cur];
    var efname = $("#js_efname"), efopts = $("#js_opts"), h = "", df = getParameter("ef");
    map_ef[df] || (df = "brokenglass");
    ef = map_ef[df] || {};
    for (var p in map_ef) {
        h += '<option value="' + encodeHTML(p) + '">' + encodeHTML(map_ef[p].params.animate) + '</option>';
    }
    efname.innerHTML = h;
    efname.value = df;
    efname.addEventListener("change", function(){
        ef = map_ef[this.value] || {};
        if (ef && ef.opts) {
            var h = "";
            for (var p in ef.opts) {
                var o = ef.opts[p];
                h += '<label class="item"><span>' + encodeHTML(o.title) + ':</span><select data-key="' + encodeHTML(p) + '">'
                for (var q in o.data) {
                    h += '<option value="' + encodeHTML(o.data[q]) + '">' + encodeHTML(q) + '</option>';
                }
                h += '</select></label>';
            }
            efopts.innerHTML = h;
        }
        efopts.style.display = ef.opts ? "" : "none";
        typeof initEf == "function" && initEf();
    });
    simulateEvent(efname, "change");
    efopts.addEventListener("change", function(e) {
        var key = e.target.getAttribute("data-key");
        if (key) {
            ef && ef.params && (ef.params[key] = e.target.value);
        }
        typeof initEf == "function" && initEf();
    });

    // function initEf() {
    // 	var next = (imglist.length - 1) * Math.random() | 0;
    // 	next == cur && (next = (next + 1) % imglist.length);
    // 	var params = ef && ef.params ? JSON.parse(JSON.stringify(ef.params)) : {};
    // 	params.target = imglist[next];
    // 	img.initEffect(params).then(function() {
    // 		cur = next;
    // 		initEf();
    // 		console.log("执行成功：")
    // 	})
    // };
    // initEf();

    // 直接执行动画
    // img.addEventListener("click", function(e){
    // 	var next = (imglist.length - 1) * Math.random() | 0;
    // 	next == cur && (next = (next + 1) % imglist.length);
    // 	var params = ef && ef.params ? JSON.parse(JSON.stringify(ef.params)) : {};
    // 	params.target = imglist[next];
    // 	params.x = e.offsetX;
    // 	params.y = e.offsetY;
    // 	cur = next;
    // 	img.execEffect(params).then(function() {
    // 		console.log("执行成功：")
    // 	})
    // });

    var efList = [], efNo = 0, oList = $(".eflist ul");
    oList.innerHTML = "";
    function doEffect(ani) {
        if (ani != null) {
            ani.no = efNo++;
            efList.push(ani);
            ani.li = doc.createElement("li");
            ani.li.innerHTML = "<span>[" + ani.no + "]" + (ani.animate || "动画") + "</span><i></i>";
            oList.appendChild(ani.li);
            if (efList.length > 1) {
                return;
            }
            $(".js_clear").innerHTML = "X 清空动画列表";
        }
        if (!efList.length) {
            $(".js_clear").innerHTML = "在图片上点击或滑动";
            return;
        }
        ani = efList[0];
        setTimeout(function(){
            var i = $("i", ani.li);
            i && (i.style.width = "90%");
        }, 0);
        img.execEffect(ani).then(function() {
            var ani = efList.shift();
            var i = $("i", ani.li);
            if (i) {
                i.style.webkitTransitionDuration = i.style.transitionDuration = ".1s";
                setTimeout(function(){
                    i.style.width = "100%";
                }, 0);
            }
            setTimeout(function(){
                oList.removeChild(ani.li);
            }, 150);
            doEffect();
        })
    };
    $(".pic_body").addEventListener("click", function(e){
        var next = (imglist.length - 1) * Math.random() | 0;
        next == cur && (next = (next + 1) % imglist.length);
        var params = ef && ef.params ? JSON.parse(JSON.stringify(ef.params)) : {};
        params.target = imglist[next];
        params.x = e.offsetX;
        params.y = e.offsetY;
        cur = next;
        doEffect(params);
    });
    $(".js_clear").addEventListener("click", function(e){
        var list = efList.splice(1);
        for (var i = 0; i < list.length; i++) {
            var ani = list[i];
            ani.li && oList.removeChild(ani.li);
        };
    });
};
preloading(pageInit);

// 注册动画
// addImgEffect("test", function(callback) {
// 	[动画处理逻辑]
// 	setTimeout(callback, 800);
// })

// 初始化动画
// img.initEffect({
// 	animate: "test",
// 	target: imglist[next],
// 	audio: "//y.gtimg.cn/music/common/upload/ct/broken.mp3",
// 	fall: false
// }).then(function() {
// 	console.log("执行成功")
// })

// 直接执行动画
// img.execEffect({
// 	animate: "test",
// 	target: imglist[next],
// 	audio: "//y.gtimg.cn/music/common/upload/ct/broken.mp3",
// 	x: e.offsetX,
// 	y: e.offsetY,
// 	fall: false
// }).then(function() {
// 	console.log("执行成功")
// })

</script>
</body>
</html>